﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
using Google.Analytics.Model.Queries;
using Google.Analytics.Web.Converters;

namespace Google.Analytics.Web
{
    /// <summary>
    /// Base for the <c>Enum</c> selects such as <see cref="Metrics"/> or <see cref="Dimensions"/>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class EnumDropDownBase<T> : Control
    {
        public IList<T> SelectedItems
        {
            get 
            {
                IList<T> values = new List<T>();
                foreach (var c in Controls)
                {
                    var checkboxDropdown = (CheckboxDropdown) c;
                    if (checkboxDropdown == null) continue;

                    foreach (TreeNode node in checkboxDropdown.SelectedItems)
                    {
                        values.Add((T) Enum.Parse(typeof (T), node.Text));
                    }
                }
                return values;
            }
        }

        /// <summary>
        /// Gets or Sets the Groups that are to be shown
        /// </summary>
        [TypeConverter(typeof(CSVConverter))]
        public string[] Groups { get; set; }

        /// <summary>
        /// Overrides the <c>CreateChildControls</c> method and adds the <see cref="CheckboxDropdown"/> controls
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            //render all groups
            Type type = typeof (T);
            IDictionary<string, IList<string>> list = GetListItems(type, Groups ?? new string[0]);

            foreach (var pair in list)
                Controls.Add( new CheckboxDropdown {Title = pair.Key, Children = pair.Value.ToArray()});
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            EnsureChildControls();
        }

        /// <summary>
        /// Gets the Dictionary of Group names and Enum values belonging to the group
        /// </summary>
        /// <param name="enumType"></param>
        /// <param name="groups"></param>
        /// <returns></returns>
        private static IDictionary<string, IList<string>> GetListItems(Type enumType, string[] groups)
        {
            if (!enumType.IsEnum)
                throw new ApplicationException("GetListItems does not support non-enum types");

            IDictionary<string, IList<string>> list = new SortedDictionary<string, IList<string>>();
            foreach (FieldInfo field in enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public))
            {
                string groupName = string.Empty;
                foreach (Attribute currAttr in field.GetCustomAttributes(typeof(Group), true))
                {
                    var valueAttribute = currAttr as Group;
                    if (valueAttribute != null) groupName = valueAttribute.Text;
                }
                if(groups.Length>0)
                {
                    if (!groups.ToList().Contains(groupName)) continue;
                }

                if (!list.ContainsKey(groupName))
                {
                    list.Add(groupName, new List<string> { field.Name });
                }
                else
                {
                    list[groupName].Add(field.Name);
                }
            }
            return list;
        }
    }
}
